#pragma once
#include "util.hpp"
#include <mutex>
#include <thread>

class user_table
{
private:
    MYSQL *_mysql; // 操作句柄
    std::mutex _mutex;

public:
    user_table(const std::string &host,
               const std::string &user,
               const std::string &password,
               const std::string &db,
               const uint16_t port)
    {
        _mysql = mysql_util::mysql_create(host, user, password, db, port);
    }

    ~user_table()
    {
        mysql_util::mysql_destory(_mysql);
    }

    bool insert(Json::Value &root) // 注册时新增用户, 密码用sha2加密，设置256位, 64字符长
    {
#define insert_user "insert into user (name,password) values ('%s',sha2('%s',256))"
        char arr[1024];
        sprintf(arr, insert_user, root["name"].asCString(), root["password"].asCString());
        if (!mysql_util::mysql_query_one(_mysql, arr))
        {
            // 执行添加失败
            error_log("insert newuser error");
            return false;
        }
        return true;
    }

    bool login(Json::Value &root) // 登录验证，并返回用户信息
    {
#define login_str "select name from user where name = '%s' and password = sha2('%s',256)"
        char arr[1024];
        sprintf(arr, login_str, root["name"].asCString(), root["password"].asCString());
        MYSQL_RES *res;
        {
            // 上锁
            std::unique_lock<std::mutex> lock(_mutex);
            // 执行查询语句
            bool ret = mysql_util::mysql_query_one(_mysql, arr);
            if (ret == false)
            {
                // 执行失败
                error_log("mysql_login error");
                return false;
            }

            // 执行成功，拿出执行结果
            res = mysql_store_result(_mysql);
            if (res == nullptr)
            {
                // 执行失败
                error_log("mysql_store_result error");
                return false;
            }
        }

        int n = mysql_num_rows(res);
        if (n != 1)
        {
            // 没找到
            debug_log("find user not only one");
            return false;
        }
        // 找到目标，说明登录成功，返回数据
        MYSQL_ROW row = mysql_fetch_row(res);
        mysql_free_result(res);
        return true;
    }

    bool select_by_name(const std::string &username, Json::Value &root) // 通过用户名返回用户信息
    {
#define select_name "select id,score,total_count,win_count from user where username = '%s'"
        char arr[1024];
        sprintf(arr, select_name, username.c_str());
        MYSQL_RES *res;
        {
            // 上锁
            std::unique_lock<std::mutex> lock(_mutex);
            // 执行查询语句
            bool ret = mysql_util::mysql_query_one(_mysql, arr);
            if (ret == false)
            {
                // 执行失败
                error_log("mysql_select_by_name error");
                return false;
            }

            // 执行成功，拿出执行结果
            res = mysql_store_result(_mysql);
            if (res == nullptr)
            {
                // 执行失败
                error_log("mysql_store_result error");
                return false;
            }
        }

        int n = mysql_num_rows(res);
        if (n != 1)
        {
            // 没找到
            debug_log("find user not only one");
            return false;
        }
        // 找到目标，返回需要的用户信息
        MYSQL_ROW row = mysql_fetch_row(res);
        root["id"] = std::stoi(row[0]);
        root["score"] = std::stoi(row[1]);
        root["total_count"] = std::stoi(row[2]);
        root["win_cout"] = std::stoi(row[3]);
        mysql_free_result(res);
        return true;
    }

    bool select_by_id(int id, Json::Value &root)
    {
#define select_id "select username,score,total_count,win_count from user where id = %d"
        char arr[1024];
        sprintf(arr, select_id, id);
        MYSQL_RES *res;
        {
            // 上锁
            std::unique_lock<std::mutex> lock(_mutex);
            // 执行查询语句
            bool ret = mysql_util::mysql_query_one(_mysql, arr);
            if (ret == false)
            {
                // 执行失败
                error_log("mysql_select_by_id error");
                return false;
            }

            // 执行成功，拿出执行结果
            res = mysql_store_result(_mysql);
            if (res == nullptr)
            {
                // 执行失败
                error_log("mysql_store_result error");
                return false;
            }
        }

        int n = mysql_num_rows(res);
        if (n != 1)
        {
            // 没找到
            debug_log("find user not only one");
            return false;
        }
        // 找到目标，返回需要的用户信息
        MYSQL_ROW row = mysql_fetch_row(res);
        root["username"] = row[0];
        root["score"] = std::stoi(row[1]);
        root["total_count"] = std::stoi(row[2]);
        root["win_cout"] = std::stoi(row[3]);
        mysql_free_result(res);
        return true;
    }
};